package l1j.server.server.model.drop;

import java.util.ArrayList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.server.Config;
import l1j.server.server.datatables.DropItemTable;
import l1j.server.server.datatables.ItemTable;
import l1j.server.server.datatables.MapsTable;
import l1j.server.server.model.L1Character;
import l1j.server.server.model.L1Inventory;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.item.L1ItemId;
import l1j.server.server.templates.L1Drop;
import l1j.server.server.utils.Random;

public class SetDrop implements SetDropExecutor {
	private static Logger _log = Logger.getLogger(SetDrop.class.getName());
	
	// レート取得
	private static final double droprate = Math.max(0, Config.RATE_DROP_ITEMS);
	private static final double adenarate = Math.max(0, Config.RATE_DROP_ADENA);
	private static Map<Integer, ArrayList<L1Drop>> _droplist;
	
	//TODO 新增遊戲管理員 .mobdrop 線上搜尋怪物掉落
	public ArrayList<L1Drop> getDrops(final int mobID) {
		return _droplist.get(mobID);
	}
	
	/**
	 * 設置掉落資料
	 * @param droplists
	 */
	@Override
	public void addDropMap(final Map<Integer, ArrayList<L1Drop>> droplists) {
		if (_droplist != null) {
			_droplist.clear();
		}
		_droplist = droplists;
	}
	/**
	 * NPC持有物品資料取回
	 * @param npc
	 * @param inventory
	 */
	@Override
	public void setDrop(final L1NpcInstance npc, L1Character attack, final L1Inventory inventory) {
		if (droprate <= 0 && adenarate <= 0) {
			return;
		}
		double rate = 0.0;
		if(attack instanceof L1PcInstance){
			rate += ((L1PcInstance )attack).getDroprate();
		}
		setDrop(npc, inventory, rate);
	}
	
	
	@Override
	public void setDrop(L1NpcInstance npc , L1Inventory inventory , final double pcrate) {
		try{
			
			// ドロップリストの取得
			final int mobId = npc.getNpcTemplate().get_npcId();
			final ArrayList<L1Drop> dropList = _droplist.get(mobId);
			if (dropList == null) {
				return;
			}
			if(dropList.isEmpty()){
				return;
			}

			int itemId=0, itemCount=0,  addCount=0, randomChance=0 ;
			double droprateadd =1;


			/************* opqlo 掉落改寫*************/
				droprateadd += pcrate;
			/************* opqlo 掉落改寫*************/

			L1ItemInstance item;
			for (final L1Drop drop : dropList) {
				boolean ok=true;//opqlo 稀有物品掉落機率降低
				// ドロップアイテムの取得
				itemId = drop.getItemid();
				if (adenarate == 0 && itemId == L1ItemId.ADENA) {
					continue; // アデナレート０でドロップがアデナの場合はスルー
				}
				// ドロップチャンス判定
				//opqlo 掉落改寫randomChance = Random.nextInt(0xf4240) + 1;// 1000000

				randomChance = Random.nextInt(100000000) + 1;
				final double rateOfMapId = MapsTable.getInstance().getDropRate(npc.getMapId()),
						rateOfItem = DropItemTable.getInstance().getDropRate(itemId);
				final long ratetemp = (long) (drop.getChance() * droprate * rateOfMapId * rateOfItem *droprateadd * 100);
				final int allRate = (int) Math.min(ratetemp, 100000000);
				if(allRate < randomChance){
					continue;
				}
				int repeat = drop.getRepeat();
				if(repeat>0){
					for(final byte i=0; repeat>i; repeat--){
						final boolean rate = Random.nextBoolean();
						if(!rate){
							ok=false;
							break;
						}
					}
				}
				if(!ok){
					repeat =0;
					continue;
				}
				// ドロップ個数を設定
				final double amount = DropItemTable.getInstance().getDropAmount(itemId);
				final int min = (int) (drop.getMin() * amount),
						max = (int) (drop.getMax() * amount);
				itemCount = min;
				addCount = max - min + 1;
				if (addCount > 1) {
					itemCount += Random.nextInt(addCount);
				}
				if (itemId == L1ItemId.ADENA) { // ドロップがアデナの場合はアデナレートを掛ける
					itemCount *= adenarate;
					npc.ADENA = itemCount;
				}
				itemCount = Math.min(itemCount, 2000000000);
				itemCount = Math.max(itemCount, 0);
				if(itemCount <=0){
					_log.log(Level.SEVERE , "掉落道具數量小於0...itemId= "+itemId);
					continue;
				}
				// アイテムの生成
				item = ItemTable.getInstance().createItem(itemId);
				if(item == null){
					_log.log(Level.SEVERE , "掉落道具不存在...itemId= "+itemId);
					continue;
				}
				if(item.isStackable()){
					item.setCount(itemCount);
				}else{
					item.setCount(1);
				}
				final int bless =drop.getBless();
				if(bless !=1){
					item.setBless(bless);
					item.setIdentified(true);
				}
				// アイテム格納
				//			System.out.println(item.getLogName());
				inventory.storeItem(item);
			}
		}catch(Exception e){
			_log.log(Level.SEVERE ,  e.getLocalizedMessage() , e);
		}
	}
}
